package com.gph.saviorframework.wf.service.impl;

import com.gph.saviorframework.wf.service.ActivitiBpmnModelService;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;

/**
 * Created by root on 16-7-9.
 */
public class ActivitiBpmnModelServiceImpl implements ActivitiBpmnModelService {

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 根据流程编号获取bpmn模型,可以用作动态的操作节点
     *
     * @param defId
     * @return
     */
    public BpmnModel getBpmnModelByDefId(String defId) {
        return repositoryService.getBpmnModel(defId);
    }

    /**
     * 获取某流程定义中所有的流程元素
     *
     * @param defId
     * @return
     */
    public Collection<FlowElement> getFlowElements(String defId) {
        return getBpmnModelByDefId(defId).getMainProcess().getFlowElements();
    }

    /****
     * 以下接口对element的操作
     *
     * @param process
     * @param userTask
     ****/
    public void addUserTask(org.activiti.bpmn.model.Process process, UserTask userTask) {
        if(process!=null){
            process.addFlowElement(userTask);
        }
    }

    /**
     * 在两个元素之间添加连接线
     *
     * @param process
     * @param sourceElementId
     * @param targetElementId
     */
    public void addSequenceFlow(Process process, String sourceElementId, String targetElementId) {
        SequenceFlow flow = new SequenceFlow();
        flow.setSourceRef(sourceElementId);
        flow.setTargetRef(targetElementId);

        process.addFlowElement(flow);
    }

    /**
     * 创建用户任务，目前仅支持确定的分配人
     *
     * @param id
     * @param name
     * @param assignee
     */
    public UserTask createUserTask(String id, String name, String assignee) {
        UserTask userTask = new UserTask();
        userTask.setName(name);
        userTask.setId(id);
        userTask.setAssignee(assignee);

        return userTask;
    }

    /**
     * 动态的添加任务节点（类似pre->newTask->next）
     *
     * @param process     流程
     * @param newTask     新节点
     * @param preElement  新节点的上级节点
     * @param nextElement 新节点的下级节点
     */
    public void addUserTask(Process process, UserTask newTask, FlowElement preElement, FlowElement nextElement) {
        addUserTask(process,newTask);
        addSequenceFlow(process,preElement.getId(),newTask.getId());
        addSequenceFlow(process,newTask.getId(),nextElement.getId());
    }
}
